iT邦幫忙

2024 iThome 鐵人賽

DAY 15
0
自我挑戰組

PHP框架-Laravel自學挑戰系列 第 15

DAY 15 - 用Laravel Livewire 前端框架撰寫Form (下)

  • 分享至 

  • xImage
  •  

哈囉大家好~
時間過得好快啊,不知不覺鐵人賽的進度已經一半了/images/emoticon/emoticon17.gif
昨天完成了簡單透過form將user input儲存到資料庫的功能,今天想要來優化昨天寫的程式碼!
那就馬上開始吧~

首先,我想要增加驗證user input的部分。在使用者提交輸入資料前,先確認輸入內容是否符合要求。
當user input不符合要求時,我想要顯示對應錯誤訊息來提醒使用者。
這裡預設標題與內容欄位為必填,其中內容欄位必須五個字以上!
修改的程式碼如下:(CreatePost.php)

<?php
namespace App\Livewire;

use Livewire\Component;
use App\Models\Post;
use Livewire\Attributes\Validate;

class CreatePost extends Component
{
    #[Validate('required')] #限制必填
    public $title = ''; 
    #[Validate('required|min: 5')] #限制必填且五字以上
    public $content = '';

    public $titleError = '標題為必填欄位!'; 
    public $contentError = '內容為必填欄位且至少五字以上!';

    public function save() 
    {
        $this->validate(); #提交前先進行驗證

        Post::create([
            'title' => $this->title,
            'content' => $this->content
        ]);

        return redirect()->to('/');
    }

    public function render()
    {
        return view('livewire.create-post');
    }
}

程式碼中定義了兩個新的變數:$titleError和$contentError,當user input不符合設定的validation時,畫面上就換出現錯誤訊息。
畫面程式碼如下:(create-post.blade.php)

<div>
    <head>
        <title>Create a new Post</title>
        <meta name="csrf-token" content="{{ csrf_token() }}">
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
    </head>
    <body>
        <div class="card">
            <div class="card-header text-center font-weight-bold">
                Create a new Post HERE!
            </div>
            <div class="card-body">
            <form name="add-blog-post-form" id="add-blog-post-form" wire:submit="save">
                <div class="form-group">
                    <label>title: </label>
                    <input class="form-control" type="text" wire:model="title" />
                    <!-- validation失敗時出現的提醒內容-->
                     <div class="text-danger">
                        @error('title') <span class="error">{{ $titleError }}</span> @enderror
                     </div>
                </div>
            
                <br/>

                <div class="form-group">
                    <label>content: </label>
                    <textarea class="form-control" wire:model="content" ></textarea>
                    <!-- validation失敗時出現的提醒內容-->
                    <div class="text-danger">
                        @error('content') <span class="error">{{ $contentError }}</span> @enderror
                    </div>
                </div>
                
                <br/>
                <button class="btn btn-primary" type="submit">Save</button>
            </form>
            </div>
        </div>
    </body>
</div>

當user input不符合規定時,就會出現以下畫面:
https://ithelp.ithome.com.tw/upload/images/20240915/20168986XGG0obLEQA.png

第二個想要優化的部分就是新增CSRF攻擊防禦的程式碼。
首先要先了解什麼是「CSRF攻擊」。
CSRF(Cross-Site Request Forgery),即「跨站請求偽造」。發生的情況通常是使用者透過輸入帳號密碼,通過驗證後進入應用程式,攻擊者會誘導使用者在不知情的情況下進行未授權的操作,即冒充使用者來發送請求。通常CSRF的防禦有三種方法:

  1. CSRF Token: 網站生成隨機的CSRF Token,將Token插入表單或Request中,server在處理request的時候會驗證CSRF Token是否有效。
  2. 驗證來源(Referer/Origin): server會檢查HTTP request的header,檢查其中的來源是否合法。
  3. 利用Samesite cookie attribute: 限制cookie的傳遞範圍,限制cookie只能在同一個來源的請求中進行傳送。

在Laravel框架中,使用的是第一種方法。有內建的CSRF防禦機制,在每個Form可以自動生成CSRF Token來進行驗證,確保是使用者本人進行操作。

以下是範例程式碼:
首先,要先在前端程式碼中加入@csrf,產生一個隨機的CSRF Token插入該表單中:

<form action="https://myApiExample.com/ method="POST">
    @csrf #插入隨機生成 CSRF Token -->
    <input type="text" name="title" value="">
    <input type="text" name="content" value="">
    <button type="submit">Submit</button>
</form>

然後在撰寫邏輯的Controller中,Laravel框架會自動幫忙檢查POST, PUT, DELETE request的CSRF Token,若發現缺少CSRF Token或是Token無效,則會自動返回419 Page Expired Error。也就表示不需要在Controller中另外撰寫處理CSRF Token的邏輯。(超級方便/images/emoticon/emoticon12.gif

這裡有趣的是,因為livewire框架中的元件(在app/Livewire目錄底下的檔案)已經有內建的CSRF防禦機制,所以不需要像寫blade template時要自己插入隨機生成的CSRF Token。


今天針對Form優化的部分就簡單到這邊結束啦~
雖然還有很多可以改善的部分,但因為時間的關係就先介紹這兩個比較常用到的功能~
明天開始就正式啟動小專案了/images/emoticon/emoticon16.gif
希望接下來也能完成每天的發文任務,那就明天見囉 ByeBye!


上一篇
DAY 14 - 用Laravel Livewire前端框架撰寫Form (上)
下一篇
DAY 16 - 用Laravel做一個小專案!專案發想與架構
系列文
PHP框架-Laravel自學挑戰30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言